package com.dysoft.flesh.gl;

import com.dysoft.bones.DataManager;
import com.dysoft.flesh.RenderContext;
import com.dysoft.flesh.Renderer;
import com.sun.opengl.util.GLUT;

import javax.media.opengl.GL;
import javax.media.opengl.GLContext;

/**
 * @author Sean Micklethwaite
 *         21-Aug-2010
 */
public abstract class GLPrimitive extends DataManager.DataObject<Renderer, Object> implements Renderer {
	static GLUT glut = new GLUT();

	protected GLPrimitive() {
		super(null);
	}

	@Override
	protected Renderer construct(Object id) throws Exception {
		return this;
	}

	public static class Plane extends GLPrimitive {
		final float x, z;

		public Plane(float x, float z) {
			this.x = x;
			this.z = z;
		}

		public void render(RenderContext ctx) {
			GL gl = GLContext.getCurrent().getGL();
			gl.glBegin(GL.GL_QUADS);
			gl.glNormal3f(0.0f, 1.0f, 0.0f);
			gl.glTexCoord2f(0f,0f);
			gl.glVertex3f(-x, 0.0f, -z);
			gl.glTexCoord2f(0f,1f);
            gl.glVertex3f(-x, 0.0f, z);
			gl.glTexCoord2f(1f,1f);
            gl.glVertex3f(x, 0.0f, z);
			gl.glTexCoord2f(1f,0f);
            gl.glVertex3f(x, 0.0f, -z);
			gl.glEnd();
		}
	}

	public static class Cube extends GLPrimitive {
		final static float [][] VERTS = {
				{-1,-1,-1}, {1,-1,-1}, {1,1,-1}, {-1,1,-1},
				{-1,-1,1},  {1,-1,1},  {1,1,1},  {-1,1,1}
		};
		final static float [][] COORDS = {
				{0,0},  {1,0},  {1,1},  {0,1}
		};
		final static int [][] FACES = {
				{0,1,2,3}, {5,4,7,6},
				{4,0,3,7}, {1,5,6,2},
				{3,2,6,7}, {4,5,1,0}
		};
		final static float [][] NORMS = {
				{0,0,-1}, {0,0,1},
				{-1,0,0}, {1,0,0},
				{0,1,0}, {0,-1,0}
		};

		final float size;

		public Cube(float size) {
			this.size = (float)(size * 0.5);
		}

		public void render(RenderContext ctx) {
			GL gl = GLContext.getCurrent().getGL();

			gl.glPushMatrix();
			gl.glScalef(size, size, size);

			gl.glBegin(GL.GL_QUADS);
			for(int i = 0; i < FACES.length; i++) {

				gl.glNormal3fv(NORMS[i], 0);
				for(int j = 0; j < 4; j++) {
					gl.glTexCoord2fv(COORDS[j], 0);
					gl.glVertex3fv(VERTS[FACES[i][j]], 0);
				}
			}
			gl.glEnd();

			gl.glPopMatrix();
		}
	}
}
